# -*- coding: utf-8 -*-
import os, stat
import threading
from time import mktime
from datetime import datetime, timedelta
from mimetypes import guess_type
from random import randint
from functools import wraps
from os.path import dirname, abspath, join, isfile
from StringIO import StringIO
from werkzeug.exceptions import NotFound
from werkzeug.utils import redirect
from ..globals import request
from ..wrappers import Response
from ..wsgiapps.jsonrpc import WSGIJSONRPCApplication
from ..wsgiapps.xmlrpc import WSGIXMLRPCApplication


_base_path = abspath(join(dirname(__file__), ".."))
def render_captcha(session_key="checkcode"):
    import captchaimage
    import Image, ImageDraw
    #text = md5(str(datetime.now())).hexdigest()[:4]
    text = "%04d"%randint(0, 9999)
    request.client_session[session_key] = text.lower()
    size_x = 30
    size_y = 40
    image_data = captchaimage.create_image(
        join(_base_path, "roughage.ttf"), size_x, size_y, text
    )
    image = Image.fromstring(
            "L", (len(image_data) / size_y, size_y), image_data
    )
    #draw = ImageDraw.Draw(image)
    #linecolor = (0,0,0)
    #for i in range(3):
    #    x1 = randint(0, size_x*4)
    #    x2 = randint(0, size_x*4)
    #    y1 = randint(0, size_y)
    #    y2 = randint(0, size_y)
    #    draw.line([(x1, y1), (x2, y2)])
    #del draw
    buf = StringIO()
    image.save(buf, "png")
    return Response(buf.getvalue(), mimetype="image/jpeg",
            headers=[('Expires', '0'), ('Pragma', 'no-cache')])


def serve_static(static_dir):
    path = request.kwargs.get("path")
    if path is None:
        filename = static_dir
    else:
        filename = join(static_dir, path)
    if not isfile(filename):
        raise NotFound
    type, encoding = guess_type(filename)
    type = type or 'application/octet-stream'
    real_mtime = os.stat(filename)[stat.ST_MTIME]
    if request.if_modified_since:
        ask_mtime = int(mktime(request.if_modified_since.timetuple()))
        if ask_mtime >= real_mtime:
            return Response(status=304)
    response = Response(mimetype=type)
    now = datetime.now()
    response.last_modified = datetime.fromtimestamp(real_mtime)
    response.expires = now + timedelta(seconds=3600)
    response.cache_control.max_age = 3600
    response.response = open(filename, 'rb')
    return response


def upload_file(path):
    if request.method == "GET":
        from jinja2 import Template
        return Response(Template(u"""
        <form enctype="multipart/form-data" method="post" action=".">
        <input type="file" name="test-file" />
        <input type="submit" value="上传" />
        </form>
        <script>
            {% for message in request.getFlashedMessages() %}
            alert('{{ message }}');
            {% endfor %}
        </script>
        """).render(request=request))
    else:
        test_file = request.files.get('test-file')
        if not test_file:
            request.flash(u"没有文件")
            return redirect(request.url)
        f = open(path, 'wb')
        while True:
            s = test_file.read(10 ** 6)
            if s:
                f.write(s)
            else:
                f.close()
                break
        request.flash(u'上传完成')
        return redirect(request.url)


# decorators
class Threaded(object):
    def __init__(self):
        self.executor = None

    def __call__(self, func):
        from concurrent.futures import ThreadPoolExecutor
        @wraps(func)
        def new_func(*args, **kwargs):
            if self.executor is None:
                self.executor = ThreadPoolExecutor(5)
            self.executor.submit(func, *args, **kwargs)
            return Response("ok")
        return new_func
threaded = Threaded()


class authenticate(object):
    def __init__(self, realm="My Protection", users=None):
        self.realm = realm
        self.users = users if users else {}

    def __call__(self, func):
        @wraps(func)
        def new_func():
            auth = request.authorization
            if auth and self.users.get(auth.username) == auth.password:
                return func()
            response = Response('Restricted Access', 401)
            response.headers['WWW-Authenticate'] = 'Basic realm="%s"'%(self.realm,)
            return response
        return new_func


def jsonrpc(cls):
    return WSGIJSONRPCApplication(instance=cls())


def xmlrpc(cls):
    return WSGIXMLRPCApplication(instance=cls())


def SOAP(tns, name=None):
    def make_wsgi(cls_or_list):
        if not isinstance(cls_or_list, list):
            cls_or_list = [cls_or_list]
        from soaplib.core.server.wsgi import Application as WSGIApplication
        from soaplib.core import Application as SOAPApplication
        return WSGIApplication(SOAPApplication(cls_or_list, tns, name))
    return make_wsgi
